<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>对象的深度克隆</title>
</head>
<body>


<!--
  1、数据类型：
    * 数据分为基本的数据类型(String, Number, boolean, Null, Undefined)和对象数据类型
    - 基本数据类型：
      特点： 存储的是该对象的实际数据
    - 对象数据类型：
      特点： 存储的是该对象在栈中引用，真实的数据存放在堆内存里
  2、复制数据
    - 基本数据类型存放的就是实际的数据，可直接复制
      let number2 = 2;
      let number1 = number2;
    - 克隆数据：对象/数组
      1、区别： 浅拷贝/深度拷贝
         判断： 拷贝是否产生了新的数据还是拷贝的是数据的引用
         知识点：对象数据存放的是对象在栈内存的引用，直接复制的是对象的引用
         let obj = {username: 'kobe'}
         let obj1 = obj; // obj1 复制了obj在栈内存的引用
      2、常用的拷贝技术
        1). arr.concat(): 数组浅拷贝
        2). arr.slice(): 数组浅拷贝
        3). JSON.parse(JSON.stringify(arr/obj)): 数组或对象深拷贝, 但不能处理函数数据
        4). 浅拷贝包含函数数据的对象/数组
        5). 深拷贝包含函数数据的对象/数组
-->
<script type="text/javascript">
    let str='a';
    let str2=str;
    console.log(str2);
    str2='b';
    console.log(str)

    let b=true;
    let b2=b;
    console.log(b2);
    b2=false;
    console.log(b);

    let obj={age:1};
    let obj2=obj;
    console.log(obj,obj2);
    obj={};
    console.log(obj,obj2);
    obj2.age=2;
    console.log(obj,obj2)

    let arr=[1,4,{username:'ke',age:33}];
    let arr2=arr;
    console.log(arr,arr2);
    arr[0]='原数组改变';
    console.log(arr,arr2);
    arr2=[];
    console.log(arr,arr2);

    let obj11={user:'ss'};
    let obj12=Object.assign(obj11);
    console.log(obj12);
    obj12.user="1111";
    console.log(obj11);

    let arr11=[1,3,{age:10},function foo() {}];
    let arr12=arr11.concat();
    console.log(arr12);
    arr12[0]='1111';
    arr12[2].age=22;
    console.log(arr11);

    let arr13=arr11.slice();//截取数组
    console.log(arr13);
    arr13[2].age='arr3age';
    console.log(arr11);


    let arr14=JSON.parse(JSON.stringify(arr11)) ;
    console.log(arr14);
    arr14[2].age="orig14";
    console.log(arr11);



    let result='abcd';
    let res1=null;
    let resarr=[1,3];
    console.log(Object.prototype.toString.call(result).slice(8,-1));
    console.log(Object.prototype.toString.call(res1).slice(8,-1));
    console.log(Object.prototype.toString.call(resarr).slice(8,-1));

    // for in 循环
  let objt={username:'ki',age:22};
  for (let i in objt){
      console.log(i)
  }

    let arrt=[1,3];
    for (let i in arrt){
        console.log(i)
    }
    //检测数据类型的函数
    function checkType(target) {
        return Object.prototype.toString.call(target).slice(8,-1)
    }
    console.log(checkType(result))
  // 实现深度克隆
  function clone(target) {
      //【按断拷贝的数据
      let result ,targetType=checkType(target);
      // 初始化变量result 称为最终克隆的数据
      if(targetType==='Object'){
          result={};
      }else if(targetType=== 'Array'){
          result =[];
      }else{
          return target;
      }

      // 遍历目标数据
      for(let i in target){
          // 获取每一个值
          let value=target[i];
          //判断目标结构里的每一项值 是否还存在对象或数组
          if(checkType(value)==='Object'||checkType(value)==='Array'){
              // 继续遍历 获取到的value
              result[i] = clone(value)
          }else{
              // 基本数据类型 或者函数
              result[i] = value;
          }
      }
      return  result
    }

    let arrtest=[1,2,3,{username:'kkkk',age:23,arrt:[2,'aaa']}];
    let arrtestclone=clone(arrtest);
    console.log(arrtestclone);
    arrtestclone[3].username='gia';
    console.log(arrtest);
</script>
</body>
</html>
</body>
</html>